home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / ax25dump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-30  |  4.4 KB  |  218 lines

  1. /* AX25 header tracing
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  /* Mods by PA0GRI */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "config.h"
  8. #ifdef AX25
  9. #include "mbuf.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "trace.h"
  13. #include "socket.h"
  14.  
  15. #ifdef TNOS_68K
  16. #define fprintf traceprintf
  17. #endif
  18.  
  19. static char *decode_type __ARGS((int16 type));
  20.  
  21. /* Dump an AX.25 packet header */
  22. void
  23. ax25_dump(fp,bpp,check)
  24. FILE *fp;
  25. struct mbuf **bpp;
  26. int check;    /* Not used */
  27. {
  28.     char tmp[AXBUF];
  29.     char frmr[3];
  30.     int control,pid,seg;
  31.     int16 type;
  32.     int unsegmented;
  33.     struct ax25 hdr;
  34.     char *hp;
  35.  
  36.     fprintf(fp,"AX25: ");
  37.     /* Extract the address header */
  38.     if(ntohax25(&hdr,bpp) < 0){
  39.         /* Something wrong with the header */
  40.         fprintf(fp," bad header!\n");
  41.         return;
  42.     }
  43.     fprintf(fp,"%s",pax25(tmp,hdr.source));
  44.     fprintf(fp,"->%s",pax25(tmp,hdr.dest));
  45.     if(hdr.ndigis > 0){
  46.         fprintf(fp," v");
  47.         for(hp = hdr.digis[0]; hp < &hdr.digis[hdr.ndigis][0];
  48.          hp += AXALEN){
  49.             /* Print digi string */
  50.             fprintf(fp," %s%s",pax25(tmp,hp),
  51.              (hp[ALEN] & REPEATED) ? "*":"");
  52.         }
  53.     }
  54.     if((control = PULLCHAR(bpp)) == -1)
  55.         return;
  56.  
  57. #ifdef TNOS_68K
  58.     fprintf(fp, " ");
  59. #else
  60.     putc(' ',fp);
  61. #endif
  62.     type = ftype(control);
  63.     fprintf(fp,"%s",decode_type(type));
  64.     /* Dump poll/final bit */
  65.     if(control & PF){
  66.         switch(hdr.cmdrsp){
  67.         case LAPB_COMMAND:
  68.             fprintf(fp,"(P)");
  69.             break;
  70.         case LAPB_RESPONSE:
  71.             fprintf(fp,"(F)");
  72.             break;
  73.         default:
  74.             fprintf(fp,"(P/F)");
  75.             break;
  76.         }
  77.     }
  78.     /* Dump sequence numbers */
  79.     if((type & 0x3) != U)    /* I or S frame? */
  80.         fprintf(fp," NR=%d",(control>>5)&7);
  81.     if(type == I || type == UI){    
  82.         if(type == I)
  83.             fprintf(fp," NS=%d",(control>>1)&7);
  84.         /* Decode I field */
  85.         if((pid = PULLCHAR(bpp)) != -1){    /* Get pid */
  86.             if(pid == PID_SEGMENT){
  87.                 unsegmented = 0;
  88.                 seg = PULLCHAR(bpp);
  89.                 fprintf(fp,"%s remain %u",seg & SEG_FIRST ?
  90.                  " First seg;" : "",seg & SEG_REM);
  91.                 if(seg & SEG_FIRST)
  92.                     pid = PULLCHAR(bpp);
  93.             } else
  94.                 unsegmented = 1;
  95.  
  96.             switch(pid){
  97.             case PID_SEGMENT:
  98. #ifdef TNOS_68K
  99.                 fprintf (fp, "\n");
  100. #else
  101.                 putc('\n',fp);
  102. #endif
  103.                 break;    /* Already displayed */
  104.             case PID_ARP:
  105.                 fprintf(fp," pid=ARP (0x%x)\n",pid);
  106.                 arp_dump(fp,bpp);
  107.                 break;
  108.             case PID_RARP:
  109.                 fprintf(fp," pid=RARP (0x%x)\n",pid);
  110.                 arp_dump(fp,bpp);
  111.                 break;
  112.             case PID_NETROM:
  113.                 fprintf(fp," pid=NET/ROM (0x%x)\n",pid);
  114.                 /* Don't verify checksums unless unsegmented */
  115. #ifdef NETROM
  116.                 netrom_dump(fp,bpp,unsegmented);
  117. #endif
  118.                 break;
  119.             case PID_IP:
  120.                 fprintf(fp," pid=IP (0x%x)\n",pid);
  121.                 /* Don't verify checksums unless unsegmented */
  122.                 ip_dump(fp,bpp,unsegmented);
  123.                 break;
  124.             case PID_X25:
  125.                 fprintf(fp," pid=X.25 (0x%x)\n",pid);
  126.                 break;
  127.             case PID_TEXNET:
  128.                 fprintf(fp," pid=TEXNET (0x%x)\n",pid);
  129.                 break;
  130.             case PID_NO_L3:
  131.                 fprintf(fp," pid=Text (0x%x)\n",pid);
  132.                 break;
  133.             default:
  134.                 fprintf(fp," pid=0x%x\n",pid);
  135.             }
  136.         }
  137.     } else if(type == FRMR && pullup(bpp,frmr,3) == 3){
  138.         fprintf(fp,": %s",decode_type(ftype(frmr[0])));
  139.         fprintf(fp," Vr = %d Vs = %d",(frmr[1] >> 5) & MMASK,
  140.             (frmr[1] >> 1) & MMASK);
  141.         if(frmr[2] & W)
  142.             fprintf(fp," Invalid control field");
  143.         if(frmr[2] & X)
  144.             fprintf(fp," Illegal I-field");
  145.         if(frmr[2] & Y)
  146.             fprintf(fp," Too-long I-field");
  147.         if(frmr[2] & Z)
  148.             fprintf(fp," Invalid seq number");
  149. #ifdef TNOS_68K
  150.             fprintf (fp, "\n");
  151. #else
  152.             putc('\n',fp);
  153. #endif
  154.     } else
  155. #ifdef TNOS_68K
  156.         fprintf (fp, "\n");
  157. #else
  158.         putc('\n',fp);
  159. #endif
  160.  
  161. }
  162. static char *
  163. decode_type(type)
  164. int16 type;
  165. {
  166.     switch(type){
  167.     case I:
  168.         return "I";
  169.     case SABM:
  170.         return "SABM";
  171.     case DISC:
  172.         return "DISC";
  173.     case DM:
  174.         return "DM";
  175.     case UA:
  176.         return "UA";
  177.     case RR:
  178.         return "RR";
  179.     case RNR:
  180.         return "RNR";
  181.     case REJ:
  182.         return "REJ";
  183.     case FRMR:
  184.         return "FRMR";
  185.     case UI:
  186.         return "UI";
  187.     default:
  188.         return "[invalid]";
  189.     }
  190. }
  191.  
  192. /* Return 1 if this packet is directed to us, 0 otherwise. Note that
  193.  * this checks only the ultimate destination, not the digipeater field
  194.  */
  195. int
  196. ax_forus(iface,bp)
  197. struct iface *iface;
  198. struct mbuf *bp;
  199. {
  200.     struct mbuf *bpp;
  201.     char dest[AXALEN];
  202.  
  203.     /* Duplicate the destination address */
  204.     if(dup_p(&bpp,bp,0,AXALEN) != AXALEN){
  205.         free_p(bpp);
  206.         return 0;
  207.     }
  208.     if(pullup(&bpp,dest,AXALEN) < AXALEN)
  209.         return 0;
  210.     if(addreq(dest,iface->hwaddr))
  211.         return 1;
  212.     else
  213.         return 0;
  214. }
  215.  
  216. #endif /* AX25 */
  217.  
  218.